#include    <string.h>
#include    <stdio.h>
#include    <malloc.h>

#include    "TST_Espc.h"

#include    "Generico.h"
#include    "LerParm.h"

#include    "Matriz.h"

#ifdef _DEBUG
#include    "CESPDIN.h"
#include    "conta.h"
#endif


static const char RESET_MATRIZ_CMD			[ ] = "=resetteste"     ;
static const char CRIAR_MATRIZ_CMD			[ ] = "=criarmat"     ;
static const char DESTRUIR_MATRIZ_CMD		[ ] = "=destruirmat"  ;
static const char ESVAZIAR_MATRIZ_CMD		[ ] = "=esvaziarmat"  ;
static const char INS_ELEM_CMD				[ ] = "=inselem"   ;
static const char OBTER_VALOR_CMD			[ ] = "=obtervalorelem" ;
static const char EXC_ELEM_CMD				[ ] = "=excluirelem"    ;

#ifdef _DEBUG
	/* Comandos do modo _DEBUG */
	static const char DETURPAR_MAT_CMD			[ ] = "=deturparmat"    ;
	static const char VERIFICAR_MAT_CMD			[ ] = "=verificarmat"    ;
	static const char ZERAR_CONTADORES_CMD		[ ] = "=zerarcontadores"	;
	static const char VER_MEMORIA_CMD			[ ] = "=verificarmemoria"	;
#ifdef _DEBUG

#define TRUE  1
#define FALSE 0

#define VAZIO     0
#define NAO_VAZIO 1

#define DIM_VT_MATRIZ   10
#define DIM_VALOR     100

MAT_tppMatriz   vtMatrizes[ DIM_VT_MATRIZ ] ;

/* Protótipo das funções encapsuladas */
static void DestruirValor( void * pValor ) ;
static int ValidarInxMatriz( int inxMatriz , int Modo ) ;

/*
* Função de teste do módulo matriz.
*
* Commando de script:
* =resetteste			
* =criarmat		inxMatriz	xMatriz		yMatriz
* =esvaziarmat		inxMatriz
* =destruirmat		inxMatrix
* =inselem			inxMatriz	StringDado	xMatriz		yMatriz		CondEsp
* =obtervalorelem	inxMatriz	xMatriz		yMatriz		ValEsp
* =excluirelem		inxMatriz	xMatriz		yMatriz		CondEsp
*/

TST_tpCondRet TST_EfetuarComando( char * ComandoTeste )
{

	int inxMatriz  = -1 ,
		numLidos   = -1 ,
		CondRetEsp = -1 ,
		xMatriz	 = -1 ,
		yMatriz    = -1,
		modoDeturpar = -1;

	TST_tpCondRet CondRet ;

	char   StringDado[ DIM_VALOR ] ;
	char * pDado ;

	char * ValEsp ;

	int i ;

	int numElem = -1 ;

	StringDado[ 0 ] = 0 ;

	/* Efetuar reset de teste de matriz */

	if ( strcmp( ComandoTeste , RESET_MATRIZ_CMD ) == 0 )
	{

		for( i = 0 ; i < DIM_VT_MATRIZ ; i++ )
		{
			vtMatrizes[ i ] = NULL ;
		} 

		return TST_CondRetOK ;

	} 

	/* Testar MAT_Criar */

	else if ( strcmp( ComandoTeste , CRIAR_MATRIZ_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "iii" ,
			&inxMatriz, &xMatriz, &yMatriz ) ;

		if ( ( numLidos != 3 )
			|| ( ! ValidarInxMatriz( inxMatriz , VAZIO )))
		{
			return TST_CondRetParm ;
		} 

		vtMatrizes[ inxMatriz ] =
			MAT_Criar( xMatriz, yMatriz, DestruirValor ) ;

		return TST_CompararPonteiroNulo( 1 , vtMatrizes[ inxMatriz ] ,
			"Erro em ponteiro de nova lista."  ) ;

	}

	/* Testar MAT_Esvaziar */

	else if ( strcmp( ComandoTeste , ESVAZIAR_MATRIZ_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "i" ,
			&inxMatriz ) ;

		if ( ( numLidos != 1 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )))
		{
			return TST_CondRetParm ;
		} 

		MAT_Esvaziar( vtMatrizes[ inxMatriz ] ) ;

		return TST_CondRetOK ;

	} 

	/* Testar MAT_Destruir */

	else if ( strcmp( ComandoTeste , DESTRUIR_MATRIZ_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "i" ,
			&inxMatriz ) ;

		if ( ( numLidos != 1 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )))
		{
			return TST_CondRetParm ;
		} 

		MAT_Destruir( vtMatrizes[ inxMatriz ] ) ;
		vtMatrizes[ inxMatriz ] = NULL ;

		return TST_CondRetOK ;

	}

	/* Testar MAT_Inserir */

	else if ( strcmp( ComandoTeste , INS_ELEM_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "isiii" ,
			&inxMatriz , StringDado , &xMatriz, &yMatriz, &CondRetEsp ) ;

		if ( ( numLidos != 5 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )) )
		{
			return TST_CondRetParm ;
		} 

		pDado = ( char * ) malloc( strlen( StringDado ) + 1 ) ;
		if ( pDado == NULL )
		{
			return TST_CondRetMemoria ;
		} 

		strcpy( pDado , StringDado ) ;


		CondRet = MAT_Inserir( vtMatrizes[ inxMatriz ] , pDado, xMatriz, yMatriz ) ;

		if ( CondRet != MAT_CondRetOK )
		{
			free( pDado ) ;
		} 

		return TST_CompararInt( CondRetEsp , CondRet ,
			"Condicao de retorno errada ao inserir."                   ) ;

	}       

	/* Testar MAT_Excluir */

	else if ( strcmp( ComandoTeste , EXC_ELEM_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "iiii" ,
			&inxMatriz , &xMatriz, &yMatriz, &CondRetEsp ) ;

		if ( ( numLidos != 4 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )) )
		{
			return TST_CondRetParm ;
		}

		return TST_CompararInt( CondRetEsp ,
			MAT_Remover( vtMatrizes[ inxMatriz ], xMatriz, yMatriz ) ,
			"Condição de retorno errada ao excluir."   ) ;

	} 

	/* Testar MAT_Obter */

	else if ( strcmp( ComandoTeste , OBTER_VALOR_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "iiis" ,
			&inxMatriz , &xMatriz , &yMatriz , StringDado ) ;

		if ( ( numLidos != 4 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )) )
		{
			return TST_CondRetParm ;
		}

		pDado = ( char * ) MAT_Obter( vtMatrizes[ inxMatriz ], xMatriz, yMatriz ) ;            

		if ( pDado == NULL )
		{
			return TST_CompararString( "" , StringDado ,
				"Dado tipo um deveria existir." ) ;
		}

		if ( StringDado == "" )
		{
			return TST_CompararPonteiroNulo( 0 , pDado ,
				"Valor não deveria existir." ) ;
		}

		return TST_CompararString( StringDado , pDado ,
			"Valor do elemento errado." ) ;			

	}

#ifdef _DEBUG

	/* Testar MAT_Deturpar */

	else if ( strcmp( ComandoTeste , DETURPAR_MAT_CMD ) == 0 )
	{				
		numLidos = LER_LerParametros( "ii" ,
			&inxMatriz , &modoDeturpar ) ;

		if ( ( numLidos != 2 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )) )
		{
			return TST_CondRetParm ;
		}

		MAT_Deturpar( vtMatrizes[ inxMatriz ], modoDeturpar ) ;
	}

	/* Testar MAT_Verificar */

	else if ( strcmp( ComandoTeste , VERIFICAR_MAT_CMD ) == 0 )
	{				
		numLidos = LER_LerParametros( "ii" ,
			&inxMatriz , &CondRetEsp ) ;

		if ( ( numLidos != 2 )
			|| ( ! ValidarInxMatriz( inxMatriz , NAO_VAZIO )) )
		{
			return TST_CondRetParm ;
		}

		CondRet = MAT_Verificar( vtMatrizes[ inxMatriz ] ) ;

		return TST_CompararInt( CondRetEsp , CondRet ,
			"Condicao de retorno errada ao verificar." ) ;
	}

	/* Zerar Contadores */

	else if ( strcmp( ComandoTeste , ZERAR_CONTADORES_CMD ) == 0 )
	{

		numLidos = LER_LerParametros( "i" , &CondRetEsp ) ;

		if( numLidos != 1 )
		{
			return TST_CondRetParm ;
		} /* if */

		CNT_ZerarContadores();
		return TST_CondRetOK;

	}

	/* Verificar vazamento de memória */
	else if ( strcmp( ComandoTeste , VER_MEMORIA_CMD ) == 0 )
	{

		CED_ExibirTodosEspacos( CED_ExibirTodos ) ;

		return TST_CondRetOK ;

	}

#endif

	return TST_CondRetNaoConhec ;

}

/* Funções encapsuladas */

/*
* Função responsável por destruir um valor.
*
* @param pValor	Pointeiro para valor a ser destruído.
* @return
*/

void DestruirValor( void * pValor )
{

	free( pValor ) ;

}


/*
* Função que valido índice da matriz.
*
* @param inxMatriz	Indice a ser validado.
* @param Modo		Modo a validar índice.
* @return			boolean	
*/

int ValidarInxMatriz( int inxMatriz , int Modo )
{

	if ( ( inxMatriz <  0 )
		|| ( inxMatriz >= DIM_VT_MATRIZ ))
	{
		return FALSE ;
	} 

	if ( Modo == VAZIO )
	{
		if ( vtMatrizes[ inxMatriz ] != 0 )
		{
			return FALSE ;
		} 
	} else
	{
		if ( vtMatrizes[ inxMatriz ] == 0 )
		{
			return FALSE ;
		} 
	} 

	return TRUE ;

} 